(function (fruit, util) {
    fruit.ui.define('fruit.graphic.Manometer', fruit.graphic.core, {
        properties: {
            value: {
                value: 0,
                observable: true
            },
            title: {
                value: '',
                observable: true
            },
            maxValue: {
                value: 100,
                observable: true
            },
            minValue: {
                value: 0,
                observable: true
            },
            warnValue: {
                value: 60,
                observable: true
            },
            unit: {
                value: ''
            },
            container: {
                value: '',
                observable: true
            },
            colors: {
                value: ["#a9d70b", "#f9c802", "#ff0000"]
            }
        },
        methods: {
            init: function (config) {
                this.inherited(config);
                this.listen("value", this._updateAnimation);
                this.listen("container", this.draw);
                this._formater = d3.format(".0%");
            },
            drawText: function (text, fontsize, y, x, color) {

                fontsize = Math.max(fontsize, 9)
                var node = this.stage.append('text')
                    .attr("text-anchor", "middle")
                    .attr('y', y)
                    .attr('font-weight', 'bold')
                    .attr('font-size', fontsize + 'px')
                    .attr('font-family', 'Arial')
                    .attr('fill', color || '#999999')
                    .text(text);
                if (x) {
                    node.attr('x', x);
                }
                return node;
            },
            getPercent: function (value) {
                var z = this.maxValue() - this.minValue(), c = value || this.value() - this.minValue();
                if (c < 0) {
                    return 0;
                }
                return c / z;
            },
            getAngle: function (value) {
                var per = this.getPercent(value), angle = per * 180 , pi = (Math.PI / 180);
                if (per * 100 >= 90) {
                    return (angle - 90) * pi;
                } else {
                    return -(90 - angle) * pi;
                }
            },
            getColor: function (value) {
                var colors = this.colors(), n = colors.length, i, per = this.getPercent(value), step = 1 / (n - 1);
                if (n === 1) {
                    return this.collors[0];
                }
                if (!this._colors) {
                    this._colors = [];
                    for (i = 0; i < n; i++) {
                        this._colors.push(util.color.hex2rgb(colors[i]))
                    }
                }
                var lower, upper , range
                //if per =1 the color will error.
                per = Math.max(per - 0.01, 0);
                for (i = 0; i < n; i++) {
                    if (per < step * i) {
                        lower = this._colors[i - 1];
                        upper = this._colors[i];
                        range = i * step - (i - 1) * step;
                        pctUpper = (per - (i - 1) * step) / range;
                        pctLower = 1 - pctUpper;
                        if (!lower || !upper) {
                            debugger
                        }
                        var color = {
                            r: Math.floor(lower.r * pctLower + upper.r * pctUpper),
                            g: Math.floor(lower.g * pctLower + upper.g * pctUpper),
                            b: Math.floor(lower.b * pctLower + upper.b * pctUpper)
                        };
                        return 'rgb(' + [color.r, color.g, color.b].join(',') + ')';
                    }
                }

            },
            draw: function (sender, args) {
                var renderTo = this.container();
                var toEl = fruit.ui.Element.resolve(document.getElementById(renderTo));
                var height = this.height() || $(renderTo).height(), width = this.width() || $(renderTo).width();
                var pi = Math.PI, step = pi / 180;
                var radius = Math.min(height, width) / 2 , arcWidth = radius * 1 / 3;

                var arc = this._arc = d3.svg.arc()
                    .innerRadius(radius - arcWidth)
                    .outerRadius(radius)
                    .startAngle(-90 * step)
                    .endAngle(90 * step);

                var stage = this.stage = this.svg.append("g")
                    // var stage = this.stage =  d3.select(renderTo).append("svg")
                    .attr("width", width)
                    .attr("height", height)
                    .attr("transform", "translate(" + width / 2 + "," + height * 3 / 4 + ")");

                stage.append("path")
                    .attr('fill', '#dedede')
                    .attr('class', 'background')
                    .attr("d", arc);
                //draw title
                this.drawText(this.title(), arcWidth * 2 / 3, -(radius + arcWidth / 2));

                //draw label
                this.drawText(this.minValue(), arcWidth / 3, 15, -(radius - arcWidth / 2));
                this.drawText(this.maxValue(), arcWidth / 3, 15, radius - arcWidth / 2);
                this._label = this.drawText(this._formater(this.getPercent()), arcWidth, -arcWidth / 2, null, "#333");

                this.drawText(this.unit(), arcWidth / 3, 5);

                this._bar = stage.append("path")
                    .attr('fill', this.getColor())
                    .attr("d", arc.endAngle(this.getAngle()));

                this.appendTo(toEl);

            },
            _updateAnimation: function (sender, obj) {
                var start = obj.oldValue, change = obj.newValue - start, me = this;

                fruit.util.Animation.create(function (progress) {
                    var value = start + progress * change;
                    me._updateValue(value);
                }, 600, 60).start();
            },
            _updateValue: function (value) {
                var me = this;
                me._bar.attr("d", me._arc.endAngle(me.getAngle(value)))
                    .attr("fill", me.getColor(value));
                me._label.text(me._formater(me.getPercent(value)));
            }
        }
    })
})(fruit, fruit.util);